﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Business.Machine.Enums;
using RotovapPlatform.Domain.Common;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace RotovapPlatform.Domain.Services.Devices
{
	/// <summary>
	/// 设备领域服务实现
	/// 负责设备模式切换和状态管理的领域逻辑
	/// </summary>
	public class DeviceDomainService : IDeviceDomainService, IDisposable
	{
		private readonly IDeviceManager _deviceManager;
		private readonly IDeviceStatusService _deviceStatusService;
		private readonly ILogger<DeviceDomainService> _logger;
		private DeviceEnums.DeviceMode _currentMode;
		private DeviceEnums.DeviceStatus _currentStatus;
		private bool _isMonitoring = false;

		public event EventHandler<DeviceModeChangedEventArgs> DeviceModeChanged;
		public event EventHandler<DeviceStatusChangedEventArgs> DeviceStatusChanged;

		public DeviceDomainService(
			IDeviceManager deviceManager,
			IDeviceStatusService deviceStatusService,
			ILogger<DeviceDomainService> logger)
		{
			_deviceManager = deviceManager ?? throw new ArgumentNullException(nameof(deviceManager));
			_deviceStatusService = deviceStatusService ?? throw new ArgumentNullException(nameof(deviceStatusService));
			_logger = logger ?? throw new ArgumentNullException(nameof(logger));

			// 初始化状态
			_currentMode = DeviceEnums.DeviceMode.Manual;
			_currentStatus = DeviceEnums.DeviceStatus.Idle;
		}

		/// <summary>
		/// 获取当前设备模式
		/// </summary>
		public async Task<DeviceEnums.DeviceMode> GetCurrentDeviceModeAsync()
		{
			try
			{
				_logger.LogDebug("领域服务: 获取当前设备模式");

				// 这里模拟获取设备模式的逻辑
				// 在实际系统中可能需要通过设备管理器或其他方式获取
				await Task.CompletedTask; // 防止编译器警告

				_logger.LogDebug($"领域服务: 当前设备模式: {_currentMode}");
				return _currentMode;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 获取当前设备模式时发生错误");
				// 默认返回维护模式
				return DeviceEnums.DeviceMode.Maintenance;
			}
		}

		/// <summary>
		/// 设置设备模式
		/// </summary>
		public async Task<OperationResult> SetDeviceModeAsync(DeviceEnums.DeviceMode mode)
		{
			try
			{
				_logger.LogInformation($"领域服务: 正在设置设备模式为: {mode}");

				// 检查模式是否可用
				if (!await IsModeAvailableAsync(mode))
				{
					_logger.LogWarning($"领域服务: 设备模式 {mode} 当前不可用");
					return new OperationResult { Success = false, Message = $"设备模式 {mode} 当前不可用" };
				}

				// 这里模拟设置设备模式的逻辑
				// 在实际系统中可能需要通过设备管理器或其他方式设置
				await Task.Delay(100); // 模拟操作延迟

				// 更新当前模式并触发事件
				if (_currentMode != mode)
				{
					_currentMode = mode;
					OnDeviceModeChanged(mode);

					// 状态可能随着模式变化而变化，更新并触发状态事件
					var status = DetermineDeviceStatus(mode);
					if (_currentStatus != status)
					{
						_currentStatus = status;
						OnDeviceStatusChanged(status);
					}
				}

				return new OperationResult { Success = true, Message = $"设备模式已成功设置为: {mode}" };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"领域服务: 设置设备模式为 {mode} 时发生错误");
				return new OperationResult { Success = false, Message = $"设置设备模式时发生错误: {ex.Message}" };
			}
		}

		/// <summary>
		/// 获取设备状态
		/// </summary>
		public async Task<DeviceEnums.DeviceStatus> GetDeviceStatusAsync()
		{
			try
			{
				_logger.LogDebug("领域服务: 获取当前设备状态");

				// 根据当前模式确定设备状态
				var deviceStatus = DetermineDeviceStatus(_currentMode);

				_logger.LogDebug($"领域服务: 当前设备状态: {deviceStatus}");
				return deviceStatus;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 获取设备状态时发生错误");
				// 默认返回错误状态
				return DeviceEnums.DeviceStatus.Error;
			}
		}

		/// <summary>
		/// 获取可用的设备模式列表
		/// </summary>
		public async Task<DeviceEnums.DeviceMode[]> GetAvailableModesAsync()
		{
			try
			{
				_logger.LogInformation("领域服务: 获取可用设备模式列表");

				// 模拟获取可用模式的逻辑，实际项目中应根据设备状态判断
				var availableModes = new DeviceEnums.DeviceMode[]
				{
					DeviceEnums.DeviceMode.SingleMachineAutomatic,
					DeviceEnums.DeviceMode.OnlineAutomatic,
					DeviceEnums.DeviceMode.Manual,
					DeviceEnums.DeviceMode.Maintenance
				};

				_logger.LogInformation($"领域服务: 可用的设备模式: {string.Join(", ", availableModes)}");
				return availableModes;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 获取可用设备模式列表时发生错误");
				// 出错时返回所有模式
				return Enum.GetValues(typeof(DeviceEnums.DeviceMode)).Cast<DeviceEnums.DeviceMode>().ToArray();
			}
		}

		/// <summary>
		/// 检查指定模式是否可用
		/// </summary>
		public async Task<bool> IsModeAvailableAsync(DeviceEnums.DeviceMode mode)
		{
			try
			{
				_logger.LogInformation($"领域服务: 检查设备模式 {mode} 是否可用");

				// 模拟检查模式是否可用的逻辑，实际项目中应根据设备状态判断
				// 这里假设所有模式都可用
				var availableModes = await GetAvailableModesAsync();
				bool isAvailable = availableModes.Contains(mode);

				_logger.LogInformation($"领域服务: 设备模式 {mode} {(isAvailable ? "可用" : "不可用")}");
				return isAvailable;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"领域服务: 检查设备模式 {mode} 是否可用时发生错误");
				// 出错时默认返回true
				return true;
			}
		}

		/// <summary>
		/// 开始监控设备状态
		/// </summary>
		public Task StartMonitoringAsync()
		{
			if (_isMonitoring)
				return Task.CompletedTask;

			_logger.LogInformation("领域服务: 开始监控设备状态");

			// 初始化状态
			_ = InitializeStatusAsync();

			// 订阅设备状态服务的状态变更事件，而不是使用定时器
			//_deviceStatusService.DeviceStatusChanged += OnDeviceStatusServiceStatusChanged;
			_isMonitoring = true;

			return Task.CompletedTask;
		}

		/// <summary>
		/// 停止监控设备状态
		/// </summary>
		public Task StopMonitoringAsync()
		{
			if (!_isMonitoring)
				return Task.CompletedTask;

			_logger.LogInformation("领域服务: 停止监控设备状态");

			// 取消事件订阅，而不是停止定时器
			_deviceStatusService.DeviceStatusChanged -= OnDeviceStatusServiceStatusChanged;
			_isMonitoring = false;

			return Task.CompletedTask;
		}

		/// <summary>
		/// 初始化状态
		/// </summary>
		private async Task InitializeStatusAsync()
		{
			try
			{
				// 获取并设置初始模式
				_currentMode = await GetCurrentDeviceModeAsync();
				OnDeviceModeChanged(_currentMode);

				// 获取并设置初始状态
				_currentStatus = await GetDeviceStatusAsync();
				OnDeviceStatusChanged(_currentStatus);

				_logger.LogInformation($"领域服务: 状态初始化完成。当前模式: {_currentMode}, 当前状态: {_currentStatus}");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 初始化状态时发生错误");
			}
		}

		/// <summary>
		/// 处理设备状态服务的状态变更事件
		/// </summary>
		private async void OnDeviceStatusServiceStatusChanged(object sender, DeviceStatusEventArgs e)
		{
			try
			{
				// 仅在状态有变化时更新和记录日志，避免频繁输出
				var mode = await GetCurrentDeviceModeAsync();
				if (_currentMode != mode)
				{
					_logger.LogDebug($"领域服务: 设备模式从 {_currentMode} 变更为 {mode}");
					_currentMode = mode;
					OnDeviceModeChanged(mode);
				}

				var status = await GetDeviceStatusAsync();
				if (_currentStatus != status)
				{
					_logger.LogDebug($"领域服务: 设备状态从 {_currentStatus} 变更为 {status}");
					_currentStatus = status;
					OnDeviceStatusChanged(status);
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 处理设备状态变更事件时发生错误");
			}
		}

		/// <summary>
		/// 触发设备模式变更事件
		/// </summary>
		protected virtual void OnDeviceModeChanged(DeviceEnums.DeviceMode mode)
		{
			try
			{
				DeviceModeChanged?.Invoke(this, new DeviceModeChangedEventArgs(mode));
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 触发设备模式变更事件时发生错误");
			}
		}

		/// <summary>
		/// 触发设备状态变更事件
		/// </summary>
		protected virtual void OnDeviceStatusChanged(DeviceEnums.DeviceStatus status)
		{
			try
			{
				DeviceStatusChanged?.Invoke(this, new DeviceStatusChangedEventArgs(status));
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "领域服务: 触发设备状态变更事件时发生错误");
			}
		}

		/// <summary>
		/// 根据设备模式确定设备状态
		/// </summary>
		private DeviceEnums.DeviceStatus DetermineDeviceStatus(DeviceEnums.DeviceMode mode)
		{
			// 这里是简化的逻辑，实际应用中可能需要考虑更多因素
			return mode switch
			{
				DeviceEnums.DeviceMode.SingleMachineAutomatic => DeviceEnums.DeviceStatus.Idle,
				DeviceEnums.DeviceMode.OnlineAutomatic => DeviceEnums.DeviceStatus.Standby,
				DeviceEnums.DeviceMode.Manual => DeviceEnums.DeviceStatus.Idle,
				DeviceEnums.DeviceMode.Maintenance => DeviceEnums.DeviceStatus.InMaintenance,
				_ => DeviceEnums.DeviceStatus.Idle
			};
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		public void Dispose()
		{
			// 确保取消事件订阅
			if (_isMonitoring)
			{
				_deviceStatusService.DeviceStatusChanged -= OnDeviceStatusServiceStatusChanged;
			}
		}

		/// <summary>
		/// 更新设备状态
		/// </summary>
		/// <param name="status">设备状态</param>
		public void UpdateDeviceStatus(DeviceEnums.DeviceStatus status)
		{
			try
			{
				_logger.LogInformation($"领域服务: 正在更新设备状态为: {status}");

				if (_currentStatus != status)
				{
					_currentStatus = status;
					OnDeviceStatusChanged(status);
					_logger.LogInformation($"领域服务: 设备状态已更新为: {status}");
				}
				else
				{
					_logger.LogDebug($"领域服务: 设备状态已经是: {status}，不需要更新");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"领域服务: 更新设备状态为 {status} 时发生错误");
			}
		}
	}
}